

//================================
// Version 1.0: Kaifa Kuang;
// 2019-5-11: Kemin Zhu;
/**
 * @file CorrectObservablesLEO.hpp
 * This class corrects observables from effects such as antenna excentricity,
 * difference in phase centers, offsets due to tide effects, etc.
 */

#ifndef CorrectObservablesLEO_HPP
#define CorrectObservablesLEO_HPP

#include <string>

#include "ProcessingClass.hpp"
#include "XvtStore.hpp"
#include "Position.hpp"
#include "constants.hpp"
#include "LEOAttitude.hpp"


namespace gpstk
{

    class CorrectObservablesLEO : public ProcessingClass
    {
    public:

         /// Default constructor.
        CorrectObservablesLEO()
            : pEphStore(NULL), pLEOAttitude(NULL),
              nominalPos(0.0, 0.0, 0.0), nominalPCO(0.0, 0.0, 0.0)
        {};


         /** Return a satTypeValueMap object, adding the new data generated
          *  when calling this object.
          *
          * @param time      Epoch corresponding to the data.
          * @param gData     Data object holding the data.
          */
        virtual satTypeValueMap& Process( const CommonTime& time,
                                          satTypeValueMap& gData )
           noexcept(false);


         /** Return a gnssSatTypeValue object, adding the new data generated
          *  when calling this object.
          *
          * @param gData    Data object holding the data.
          */

        virtual void Process(gnssRinex& gData)
           noexcept(false)
        {
           nominalPos = gData.header.srcPos; 

           cout << "nominalPos:" << nominalPos << endl;
           cout << offsetL1_SRF << endl; 
           cout << offsetL2_SRF << endl;

           if(pLEOAttitude!=NULL)
           {
               offsetL1 = pLEOAttitude->OffsetInSRF2TRF(gData.header.epoch, offsetL1_SRF);
               offsetL2 = pLEOAttitude->OffsetInSRF2TRF(gData.header.epoch, offsetL2_SRF);
               cout << offsetL1 << endl;
               cout << offsetL2 << endl;
           }
           else
           {
               cerr << "please give pLEOAttitude!" << endl;
               exit(-1);
           }

           Process(gData.header.epoch, gData.body);

        }


        /// Return a pointer to the ephemeris object currently in use.
        virtual XvtStore<SatID> *getEphStore(void) const
        { return pEphStore; };


        /** Set ephemeris object to be used.
         *
         * @param ephStore      Ephemeris object.
         */
        virtual CorrectObservablesLEO& setEphStore(XvtStore<SatID>& ephStore)
        { pEphStore = &ephStore; return (*this); };


         /// Return nominal position of receiver.
        virtual Position getNominalPosition(void) const
        { return nominalPos; };


         /** Set nominal position of receiver.
          *
          * @param pos    Nominal position of receiver.
          */
        virtual CorrectObservablesLEO& setNominalPosition(const Position& pos)
        { nominalPos = pos; return (*this); };

        virtual CorrectObservablesLEO& setLEOAttitude(LEOAttitude& attStore)
        { pLEOAttitude = &attStore; return (*this); };

        virtual Triple getOffsetL1(void) const
        { return offsetL1; };

        virtual Triple getOffsetL2(void) const
        { return offsetL2; };

        virtual CorrectObservablesLEO& setOffsetL1(const Triple& pco)
        { offsetL1 = pco; return (*this); };

        virtual CorrectObservablesLEO& setOffsetL2(const Triple& pco)
        { offsetL2 = pco; return (*this); };

        virtual CorrectObservablesLEO& setOffsetL1SRF(const Triple& pco)
        { offsetL1_SRF = pco; return (*this); };

        virtual CorrectObservablesLEO& setOffsetL2SRF(const Triple& pco)
        { offsetL2_SRF = pco; return (*this); };

         /// Return a string identifying this object.
        virtual std::string getClassName(void) const;


         /// Destructor
        virtual ~CorrectObservablesLEO() {};


    private:

        /// Pointer to ephemeris object.
        XvtStore<SatID>* pEphStore;
        LEOAttitude* pLEOAttitude;

        /// LEO position.
        Position nominalPos;

        /// LEO PCO.
        Triple nominalPCO;

        Triple offsetL1;
        Triple offsetL2;

        Triple offsetL1_SRF;
        Triple offsetL2_SRF;


    }; // End of class 'CorrectObservablesLEO'

    //@}

}  // End of namespace gpstk

#endif  // CorrectObservablesLEO_HPP
